#include<iostream>
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>

void PrintPending(sigset_t& pending)
{
    std::cout << "[进程：" << getpid() <<"]: " << "sigpending list:";
    for(int i =31;i>0;i--)
    {
        if(sigismember(&pending , i))
        {
            std::cout << 1;
        }
        else 
        {
            std::cout << 0;
        }
    }
    std::cout << std::endl;
}

void handler(int signo)
{
    std::cout << "我获得了一个信号 : " << signo << std::endl;
    //打印pending
    sigset_t pending;
    sigemptyset(&pending);
    sigpending(&pending);
    std::cout << "##########################" << std::endl;
    PrintPending(pending);
    std::cout << "##########################" << std::endl;
}

int main()
{
    signal(SIGINT, handler);
    //屏蔽2号信号 --> 往block 中对应比特位中做写入
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigaddset(&block , 2);
    //Q:能否屏蔽所有信号？
    // for(int i = 1;i<=32;i++)
    // {
    //     sigaddset(&block , i);
    // }
    //经过实验可以发现，9 19 号信号不能捕获也不能屏蔽

    //将block 写入内核
    sigprocmask(SIG_BLOCK , &block , &oblock);

    int cnt = 10;

    //获取内核中的pending 并打印
    while(true)
    {
        sigset_t pending;
        sigemptyset(&pending);
        //从内核中获取pending
        sigpending(&pending);

        //打印
        PrintPending(pending);
        sleep(1);

        cnt--;
        if(cnt == 0)
        {
            //解除对2号信号的屏蔽就会递达，即信号2在pending 中由1->0
            std::cout << "解除对2号信号的屏蔽: " << std::endl; 
            sigprocmask(SIG_SETMASK , &oblock , nullptr);
            //2号信号的默认处理动作是结束当前进程，所以我们想要判断修改pending 是在递达前还是递达后就需要对2号信号进行signal
        }
    }
    return 0;
}